package pe.com.bbva.modpre.persistencia.hibernate;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.hibernate.SessionFactory;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import pe.com.bbva.modpre.dominio.Disponibilidad;
import pe.com.bbva.modpre.dominio.Usuario;
import pe.com.bbva.modpre.persistencia.DisponibilidadDAO;
import pe.com.bbva.modpre.utileria.Busqueda;
import pe.com.bbva.modpre.utileria.ModpreUtil;

@Repository
@SuppressWarnings("serial")
public class DisponibilidadHibernate extends BaseHibernate<Disponibilidad, Long> 
implements DisponibilidadDAO{
	
	@Value("${jdbc.schema}")
	private String schema;

	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	public String obtenerObjetoBBDD(String objetoBBDD) {
		return schema+"."+objetoBBDD;
	}
	
	@Autowired
	public DisponibilidadHibernate(SessionFactory sessionFactory){
		setSessionFactory(sessionFactory);
	}

	@Override
	public List<Disponibilidad> buscarDisponibilidad(Disponibilidad disponibilidad) {
		List<String> alias=new ArrayList<String>();
		Busqueda filtro = Busqueda.forClass(Disponibilidad.class);
		if(disponibilidad!=null){
			if(disponibilidad.getId()!=null){
				filtro.add(Restrictions.eq("id",
						disponibilidad.getId()));
			}
			if(disponibilidad.getUsuario()!=null){
				filtro.createAlias("usuario", "u");
				alias.add("u");
				filtro.add(Restrictions.ilike("u.nombres",
						disponibilidad.getUsuario().getNombres(), MatchMode.ANYWHERE));
			}
			
			if(disponibilidad.getFechaDesde()!=null && disponibilidad.getFechaHasta()!=null){
				Calendar desde=Calendar.getInstance();
				desde.setTime((Date)disponibilidad.getFechaDesde());
				desde.set(Calendar.HOUR_OF_DAY, 0);
				desde.set(Calendar.MINUTE, 0);
				desde.set(Calendar.SECOND, 0);
				desde.set(Calendar.MILLISECOND, 0);
				Calendar hasta=Calendar.getInstance();
				hasta.setTime((Date)disponibilidad.getFechaHasta());
				hasta.set(Calendar.HOUR_OF_DAY, 23);
				hasta.set(Calendar.MINUTE, 59);
				hasta.set(Calendar.SECOND, 59);
				hasta.set(Calendar.MILLISECOND, 999);
				filtro.add(Restrictions.between("fechaDesde", desde.getTime(), 
						hasta.getTime()));
			}
			if(disponibilidad.getCreacion()!=null && disponibilidad.getEdicion()!=null){
				Calendar desde=Calendar.getInstance();
				desde.setTime((Date)disponibilidad.getCreacion());
				desde.set(Calendar.HOUR_OF_DAY, 0);
				desde.set(Calendar.MINUTE, 0);
				desde.set(Calendar.SECOND, 0);
				desde.set(Calendar.MILLISECOND, 0);
				Calendar hasta=Calendar.getInstance();
				hasta.setTime((Date)disponibilidad.getEdicion());
				hasta.set(Calendar.HOUR_OF_DAY, 23);
				hasta.set(Calendar.MINUTE, 59);
				hasta.set(Calendar.SECOND, 59);
				hasta.set(Calendar.MILLISECOND, 999);
				filtro.add(Restrictions.between("fechaHasta", desde.getTime(), 
						hasta.getTime()));
			}
		}
		filtro.addOrder(Order.asc("id"));
		return buscar(filtro);
	}

	@Override
	public List<Disponibilidad> disponibilidadXSuperior(Disponibilidad disponible) {
		Usuario usuarioSesion=ModpreUtil.obtenerUsuarioSesion();
		StringBuilder sql=new StringBuilder();
		SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yy");
		sql.append("select d.*,u.*,u.id ID_USUARIO,d.id ID_DISPONIBILIDAD from "+ obtenerObjetoBBDD("cfg_disponibilidad d "));
		sql.append("inner join "+obtenerObjetoBBDD("org_integrante i ")+"on d.usuario=i.usuario ");
		sql.append("inner join "+obtenerObjetoBBDD("org_equipo e ")+"on i.equipo=e.id ");
		sql.append("inner join "+obtenerObjetoBBDD("seg_usuario u ")+"on d.usuario=u.id ");
		sql.append("where (i.superior=? or e.padre=?)");
		if(disponible!=null){
			if(disponible.getUsuario()!=null){
				sql.append(" and u.nombres||' '||u.paterno||' '||u.materno like '%"+ disponible.getUsuario().getNombres().toUpperCase() +"%' ");
			}
			if(disponible.getFechaDesde()!=null && disponible.getFechaHasta()!=null){
				Calendar desde=Calendar.getInstance();
				desde.setTime((Date)disponible.getFechaDesde());
				desde.set(Calendar.HOUR_OF_DAY, 00);
				desde.set(Calendar.MINUTE, 00);
				desde.set(Calendar.SECOND, 00);
				desde.set(Calendar.MILLISECOND, 000);
				Calendar hasta=Calendar.getInstance();
				hasta.setTime((Date)disponible.getFechaHasta());
				hasta.set(Calendar.HOUR_OF_DAY, 23);
				hasta.set(Calendar.MINUTE, 59);
				hasta.set(Calendar.SECOND, 59);
				hasta.set(Calendar.MILLISECOND, 999);
				
				
				sql.append(" and (d.fecha_desde between TO_DATE('"+ fmt.format(desde.getTime()).toString() +" 00:00:00','DD/MM/YY HH24:MI:SS')  and TO_DATE('"+ fmt.format(hasta.getTime()).toString() +" 23:59:59','DD/MM/YY HH24:MI:SS')) ");
			}
			if(disponible.getCreacion()!=null && disponible.getEdicion()!=null){
				Calendar desde=Calendar.getInstance();
				desde.setTime((Date)disponible.getCreacion());
				desde.set(Calendar.HOUR_OF_DAY, 0);
				desde.set(Calendar.MINUTE, 0);
				desde.set(Calendar.SECOND, 0);
				desde.set(Calendar.MILLISECOND, 0);
				Calendar hasta=Calendar.getInstance();
				hasta.setTime((Date)disponible.getEdicion());
				hasta.set(Calendar.HOUR_OF_DAY, 23);
				hasta.set(Calendar.MINUTE, 59);
				hasta.set(Calendar.SECOND, 59);
				hasta.set(Calendar.MILLISECOND, 999);
				
				sql.append(" and (d.fecha_hasta between TO_DATE('"+ fmt.format(desde.getTime()).toString() +" 00:00:00','DD/MM/YY HH24:MI:SS')  and TO_DATE('"+ fmt.format(hasta.getTime()).toString() +" 23:59:59','DD/MM/YY HH24:MI:SS')) ");
			}
			
		}
		
		List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql.toString(),usuarioSesion.getId(),usuarioSesion.getEquipo().getId());
		List<Disponibilidad> listaD = new ArrayList<Disponibilidad>();
		for (Map<String, Object> map : rows) {
			Disponibilidad disponibilidad = new Disponibilidad();
			Usuario usuario = new Usuario();
			usuario.setPaterno((String) map.get("PATERNO"));
			usuario.setMaterno((String) map.get("MATERNO"));
			usuario.setNombres((String) map.get("NOMBRES"));
			usuario.setId(Long.parseLong(map.get("ID_USUARIO").toString()));
			
			disponibilidad.setId(Long.parseLong(map.get("ID_DISPONIBILIDAD").toString()));
			disponibilidad.setUsuario(usuario);
			disponibilidad.setFechaDesde((Date) map.get("FECHA_DESDE"));
			disponibilidad.setFechaHasta((Date) map.get("FECHA_HASTA"));
			
		listaD.add(disponibilidad);
		}
		return listaD;		
	}
}
